package com.mayi.crm;

import com.alibaba.fastjson.JSON;
import com.mayi.crm.base.ResultInfo;
import com.mayi.crm.exceptions.NoLoginException;
import com.mayi.crm.exceptions.ParamsException;
import com.mayi.crm.interceptors.NoLoginInterceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author yacong_liu
 * @version 1.0
 * @classname GlobalExceptionResolver
 * @description 全局异常统一处理
 * @date 2021/1/13
 **/
@Component
public class GlobalExceptionResolver implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest request,
                                         HttpServletResponse response, Object handler, Exception e) {

        /**
         * 判断异常类型
         *  如果是未登录异常，则先执行登录异常相关拦截
         */
        if (e instanceof NoLoginException) {
            // 重定向到登录页面
            ModelAndView modelAndView = new ModelAndView("redirect:/index");
            return modelAndView;
        }


        // 异常处理分为两种：一种是返回视图，一种是返回JSON
        // 如果方法上带有ResponseBody注解则返回JSON，否则返回视图
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("");
        modelAndView.addObject("code", 400);
        modelAndView.addObject("msg", "系统异常，请稍后尝试...");

        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            // 获取方法上的ResponseBody注解
            ResponseBody annotation = handlerMethod.getMethod().getDeclaredAnnotation(ResponseBody.class);

            if (annotation == null) {
                //视图
                if (e instanceof ParamsException) {
                    ParamsException exception = (ParamsException) e;
                    modelAndView.addObject("code", exception.getCode());
                    modelAndView.addObject("msg", exception.getMsg());
                }
                return modelAndView;
            } else {
                //JSON
                ResultInfo result = new ResultInfo();
                result.setCode(300);
                result.setMsg("系统异常，请重试！");
                if (e instanceof ParamsException) {
                    result.setCode(((ParamsException) e).getCode());
                    result.setMsg(((ParamsException) e).getMsg());
                }
                response.setContentType("application/json;charset=utf-8");
                PrintWriter writer = null;
                try {
                    writer = response.getWriter();
                    writer.write(JSON.toJSONString(result));
                    writer.flush();
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                } finally {
                    if (writer != null) {
                        writer.close();
                    }
                }
            }

        }
        return null;
    }
}
